package com.xneure.enging.convert;

import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.InputStreamSource;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.xneure.enging.RequestContext;
import com.xneure.enging.WebContext;
import com.xneure.enging.widget.impl.Entry;
import com.xneure.utils.JsonUtil;
import com.xneure.utils.ObjectUtil;
import com.xneure.utils.bean.GUID;

public class ParamConvert implements HandlerMethodArgumentResolver{
	@Override
	public boolean supportsParameter(MethodParameter parameter){
		Class<?> parameterType = parameter.getParameterType();
		if(null != parameter.getParameterAnnotation(RequestParam.class) || null != parameter.getParameterAnnotation(RequestBody.class) || ObjectUtil.isSubclass(parameterType,InputStreamSource.class)
				|| ObjectUtil.isGeneralType(parameterType))
		{
			return ObjectUtil.isSubclass(parameterType,Map.class,List.class,Set.class) || parameterType.isArray();
		}
		return true;
	}

	@SuppressWarnings({"rawtypes","unchecked"})
	@Override
	public Object resolveArgument(MethodParameter parameter,ModelAndViewContainer mavContainer,NativeWebRequest webRequest,WebDataBinderFactory binderFactory)
			throws Exception
	{
		Class<?> parameterType = parameter.getParameterType();
		if(ObjectUtil.isSubclass(parameterType,GUID.class)){
			return GUID.valueOf(webRequest.getParameter(parameter.getParameterName()));
		}else if(ObjectUtil.isSubclass(parameterType,Entry.class)){
			return new Entry(new WebContext());
		}else if(ObjectUtil.isSubclass(parameterType,Map.class,List.class,Set.class) || parameterType.isArray()){
			Object obj = RequestContext.getReqParam(parameter.getParameterName());
			return JsonUtil.toObject(obj.toString(),parameterType.isArray() ? (Class)parameterType.getComponentType() : parameterType);
		}
		return ObjectUtil.mapToObject(RequestContext.getReqParam(),parameterType);
	}
}
